home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / visulztn / saoimage / saoimage.lha / clrctrl.c < prev    next >
C/C++ Source or Header  |  1990-04-20  |  9KB  |  302 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    clrctrl.c (Color Control)
  6.  * Purpose:    Control colors
  7.  * Subroutine:    select_color()            returns: void
  8.  * Subroutine:    control_color()            returns: void
  9.  * Subroutine:    invert_rgb()            returns: void
  10.  * Subroutine:    reinit_color()            returns: void
  11.  * Xlib call:    XStoreColors()
  12.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  13.  *        You may do anything you like with this file except remove
  14.  *        this copyright.  The Smithsonian Astrophysical Observatory
  15.  *        makes no representations about the suitability of this
  16.  *        software for any purpose.  It is provided "as is" without
  17.  *        express or implied warranty.
  18.  * Modified:    {0} Michael VanHilst    initial version           9 May 1989
  19.  *        {n} <who> -- <does what> -- <when>
  20.  */
  21.  
  22. #include <stdio.h>        /* define NULL */
  23. #include <X11/Xlib.h>        /* X window stuff */
  24. #include <X11/Xutil.h>        /* X window manager stuff */
  25. #include "hfiles/constant.h"    /* define codes */
  26. #include "hfiles/struct.h"    /* declare structure types */
  27. #include "hfiles/extern.h"    /* extern main parameter structures */
  28. #include "hfiles/cgraph.h"
  29.  
  30. extern struct cgraphRec cgraph;
  31.  
  32. #define BUTTONMASK (Button1Mask|Button2Mask|Button3Mask)
  33. #define EVENTMASK (ButtonPressMask|ButtonReleaseMask|ButtonMotionMask)
  34.  
  35. /*
  36.  * Subroutine:    select_color
  37.  * Purpose:    Things to do when a buttonbox color menu button is selected
  38.  */
  39. void select_color ( )
  40. {
  41.   static int overlay = 0;
  42.   static int cells = 0;
  43.   static int mode = VOP_PseudoColor;
  44.   void invert_rgb(), reinit_color();
  45.   static void new_color_table();
  46.  
  47.   if( control.response[0] == VOP ) {
  48.     switch( control.response[1] ) {
  49.     case 0:
  50.       /* 0 is main menu, change only main mode */
  51.       break;
  52.     case VOP_Invert:
  53.       /* invert is a toggle */
  54.       invert_rgb();
  55.       /* change records to show reverse of previous mode */
  56.       color.inverse ^= 1;
  57.       break;
  58.     case VOP_ContBias:
  59.     case VOP_ThreshSat:
  60.     case VOP_gamma:
  61.       color.control_mode = control.response[1];
  62.       break;
  63.     case VOP_Overlay:
  64.       if( color.cells.overlay ) {
  65.     color.cells.wanted = (color.cells.wanted + 2) * 2;
  66.     color.cells.overlay = 0;
  67.       } else {
  68.     color.cells.wanted = (color.cells.wanted / 2) - 2;
  69.     color.cells.overlay = 1;
  70.       }
  71.       reinit_color (1);
  72.       break;
  73.     case VOP_Halftone:
  74.       if( color.colormap_mode == VOP_Halftone ) {
  75.     color.colormap_mode = mode;
  76.     if( cells <= 1 )
  77.       color.cells.wanted = 200;
  78.     else
  79.       color.cells.wanted = cells;
  80.     color.cells.overlay = overlay;
  81.       } else {
  82.     mode = color.colormap_mode;
  83.     overlay = color.cells.overlay;
  84.     cells = color.cells.wanted;
  85.     color.colormap_mode = VOP_Halftone;
  86.     color.cells.wanted = 1;
  87.     color.cells.overlay = 0;
  88.       }
  89.       reinit_color(1);
  90.       break;
  91.     default:
  92.       break;
  93.     }
  94.     control.mode = VOP;
  95.   } else if( control.response[0] == MOP ) {
  96.     if( (control.response[1] != 0) &&
  97.     (control.response[1] != MOP_SignOff) ) {
  98.       /* install a new color set */
  99.       new_color_table(control.response[1]);
  100.     }
  101.   }
  102. }
  103.  
  104. /*
  105.  * Subroutine:    control_color
  106.  * Purpose:    Alter color based on mouse events
  107.  */
  108. void control_color ( )
  109. {
  110.   static int oldmode =VOP;
  111.   static int track;
  112.   static long motionmask = 0;
  113.   int released_button_mask;
  114.   Bool specificmotion_in_disp();    /* Function for XCheckIfEvent */
  115.   void vary_colors(), draw_cgraph();
  116.  
  117.   if( color.ncolors <= 1 )
  118.     /* trap halftone mode until we have something to do */
  119.     return;
  120.   switch( control.event.type ) {
  121.   case ButtonPress:
  122.     if( (control.event.xbutton.state & BUTTONMASK) == 0 ) {
  123.       /* if this is the beginning of a colorful relationship */
  124.       /* store current mode */
  125.       oldmode = control.mode;
  126.       control.mode = VOP;
  127.       /* events to send through here in any case */
  128.       control.priority = EVENTMASK;
  129.     }
  130.     if( control.event.xbutton.button == Button1 ) {
  131.       motionmask |= Button1Mask;
  132.     } else if( control.event.xbutton.button == Button2 ) {
  133.       motionmask |= Button2Mask;
  134.     } else if( control.event.xbutton.button == Button3 ) {
  135.       motionmask |= Button3Mask;
  136.     } else
  137.       return;
  138.   case MotionNotify:
  139.     control.completed = 1;
  140.     /* shift xor track will cause the graph to track the changes */
  141.     if( ((control.event.xmotion.state & (ShiftMask | LockMask)) !=0) ^
  142.         (control.tracking !=0) )
  143.       track = 1;
  144.     else
  145.       track = 0;
  146.     /* get only the most recent move */
  147.     XSync(control.event.xmotion.display, 0);
  148.     while( XCheckIfEvent(control.event.xmotion.display, &control.event,
  149.              specificmotion_in_disp, (char *)(&motionmask)) );
  150.     vary_colors(&control.event, color.control_mode, track,
  151.         control.event.xmotion.x, control.event.xmotion.y,
  152.         (int)dispbox.width, (int)dispbox.height);
  153.     break;
  154.   case ButtonRelease:
  155.     /* this event could only have been meant for us */
  156.     control.completed = 1;
  157.     if( !track )
  158.       /* update the color graph if any button is released and not tracking*/
  159.       draw_cgraph(0, 0);
  160.     /* which buttons were being held before? */
  161.     switch( control.event.xbutton.button ) {
  162.     case Button1:
  163.       released_button_mask = Button1Mask;
  164.       break;
  165.     case Button2:
  166.       released_button_mask = Button2Mask;
  167.       break;
  168.     case Button3:
  169.       released_button_mask = Button3Mask;
  170.       break;
  171.     default:
  172.       return;
  173.     }
  174.     motionmask ^= released_button_mask;
  175.     /* if that was the last button, we are done */
  176.     if( (control.event.xbutton.state & BUTTONMASK) == released_button_mask ) {
  177.       control.priority = 0;
  178.       control.mode = oldmode;
  179.       motionmask = 0;
  180.     }
  181.     break;
  182.   default:
  183.     break;
  184.   }
  185. }
  186.  
  187. /*
  188.  * Subroutine:    new_color_table
  189.  * Purpose:    Install a new pre-defined color table
  190.  */
  191. static void new_color_table ( map_code )
  192.      int map_code;
  193. {
  194.   int fetch_colortable();
  195.   void make_cellstore_from_tables(), draw_cgraph(), label_gamma();
  196.   void set_submenu_toggle();
  197.  
  198.   if( fetch_colortable(&color, map_code, img.filename) ) {
  199.     /* unset the inverse flag if it is set */
  200.     if( color.inverse ) {
  201.       set_submenu_toggle(VOP, VOP_Invert, 0);
  202.       color.inverse = 0;
  203.     }
  204.     make_cellstore_from_tables(&color);
  205.     /* send colors to the display */
  206.     XStoreColors(color.display, color.colormap,
  207.          color.cellstore, color.ncolors);
  208.     /* draw the graph of the colors, and relabel the gamma values */
  209.     if( graphbox.active ) {
  210.       draw_cgraph(1, 0);
  211.       label_gamma(1, 1, 1);
  212.     }
  213.   }
  214. }
  215.  
  216. /*
  217.  * Subroutine:    invert_rgb
  218.  * Purpose:    Reverse all colors at once (respond to invert button)
  219.  * Xlib call:    XStoreColors()
  220.  */
  221. void invert_rgb ( )
  222. {
  223.   void make_cellstore_from_cellmaps(), draw_cgraph();
  224.   static void invert_table();
  225.  
  226.   /* invert color tables and remake storemap */
  227.   invert_table(&color.ctable.red);
  228.   invert_table(&color.ctable.green);
  229.   invert_table(&color.ctable.blue);
  230.   make_cellstore_from_cellmaps (&color);  
  231.   XStoreColors(color.display, color.colormap,
  232.            color.cellstore, color.ncolors);
  233.   /* redraw the color graph */
  234.   if( graphbox.active )
  235.     draw_cgraph(1, 0);
  236. }
  237.  
  238. static void invert_table ( table )
  239.      struct subtableRec *table;
  240. {
  241.   double *intensity;        /* l: intensity by table vertex or cell */
  242.   int i, cnt;
  243.  
  244.   intensity = table->intensity;
  245.   cnt = table->vertex_cnt;
  246.   for( i=0; i<cnt; i++ )
  247.     intensity[i] = 1.0 - intensity[i];
  248.   intensity = table->cellmap;
  249.   cnt = table->map_sz;
  250.   for( i=0; i<cnt; i++ )
  251.     intensity[i] = 1.0 - intensity[i];
  252. }
  253.  
  254. /*
  255.  * Subroutine:    reinit_color
  256.  * Purpose:    Make necessary adjustment after a request to change use of
  257.  *        color resources
  258.  */
  259. void reinit_color ( disp )
  260.      int disp;
  261. {
  262.   void init_color(), draw_colorbar(), new_scalemap(), adjust_color_graph();
  263.   void map_panbox(), map_dispbox(), disp_panbox(), redraw_magnifier();
  264.   void adjust_main_colorbar(), label_colorbar(), disp_dispbox(), draw_cgraph();
  265.   void adjust_graph_colorbar(), clear_blink(), map_graphbox(), set_magnifier();
  266.  
  267.   init_color(&color, 0);
  268.   cursor.overwrites_image_data = (!color.cursor_overlay);
  269.   set_magnifier();
  270.   if( disp ) {
  271.     /* make the new lookup table */
  272.     new_scalemap();
  273.     /* refill display buffers with rescaled values */
  274.     redraw_magnifier();
  275.     map_panbox();
  276.     map_dispbox();
  277.     disp_panbox();
  278.     disp_dispbox();
  279.   }
  280.   adjust_main_colorbar();
  281.   draw_colorbar(0);
  282.   /* force the blinking parameters to be rechecked */
  283.   clear_blink();
  284.   if( cgraph.graph.ID != NULL ) {
  285.     if( !color.single_plane ) {
  286.       /* sometimes redundant: it also happens when the window is mapped */
  287.       adjust_color_graph();
  288.       adjust_graph_colorbar();
  289.     }
  290.     if( graphbox.active ) {
  291.       if( (color.ncolors <= 1) || color.monochrome )
  292.     /* unmap the graphbox */
  293.     map_graphbox();
  294.       else {
  295.     draw_cgraph(1, 0);
  296.     draw_colorbar(1);
  297.     label_colorbar();
  298.       }
  299.     }
  300.   }
  301. }
  302.